package com.bood.shimmer.common.utils;

import org.apache.commons.lang3.time.FastDateFormat;

import java.time.Instant;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * 生成不重复的编号
 * </p>
 *
 * @author：bood
 * @date：2020/9/25
 */
@SuppressWarnings("AlibabaConstantFieldShouldBeUpperCase")
public class ODDGenerator {

    @SuppressWarnings("AlibabaConstantFieldShouldBeUpperCase")
    private static final FastDateFormat PATTERN = FastDateFormat.getInstance("yyyyMMddHHmmss");
    @SuppressWarnings("AlibabaConstantFieldShouldBeUpperCase")
    private static final AtomicInteger ATOMICINTEGER = new AtomicInteger(1);
    private static ThreadLocal<StringBuilder> THREADLOCAL = new ThreadLocal<>();


    public ODDGenerator() {
    }


    /**
     * <p>
     * 【长码生成策略】
     * </p>
     *
     * @param lock: 随机字符串
     * @return：java.lang.String
     * @author：bood
     * @date：2020/9/25
     */
    public static String getC(String lock) {
        try {
            // 取系统当前时间作为编号前半部分
            StringBuilder builder = new StringBuilder(PATTERN.format(Instant.now().toEpochMilli()));
            // HASH-CODE
            builder.append(Math.abs(lock.hashCode()));
            // 自增顺序
            builder.append(ATOMICINTEGER.getAndIncrement());
            THREADLOCAL.set(builder);
            return String.valueOf(THREADLOCAL.get());
        } finally {
            THREADLOCAL.remove();
        }
    }

    /**
     * <p>
     * 【短码生成策略】
     * </p>
     *
     * @param lock: 随机字符串
     * @return：java.lang.String
     * @author：bood
     * @date：2020/9/25
     */
    public static String getD(String lock) {
        try {
            // 随机数
            StringBuilder builder = new StringBuilder(ThreadLocalRandom.current().nextInt(0, 999));
            // HASH-CODE
            builder.append(Math.abs(lock.hashCode()));
            // 自增顺序
            builder.append(ATOMICINTEGER.getAndIncrement());
            THREADLOCAL.set(builder);
            return String.valueOf(THREADLOCAL.get());
        } finally {
            THREADLOCAL.remove();
        }
    }

}